本文同步更新於blog
情境:以下是某攝影棚的影片製作方式
<?php
namespace App\TemplateMethodPattern\Video;
use App\TemplateMethodPattern\Video\UnboxVideo;
class Program
{
public function makeUnboxVideo()
{
return '選擇開箱項目、拍攝、剪輯出個人開箱的風格、上傳影片';
}
public function makeTutorialVideo()
{
return '設計教學內容、拍攝、剪輯出個人教學的風格、上傳影片';
}
public function makeStoryVideo()
{
return '選擇故事主題、拍攝、剪輯出個人說故事的風格、上傳影片';
}
}
老闆覺得影片製作,有些相同的環節,
希望我們開發程式解決,增加影片產生效率。
需求一:找出共同點,寫出樣板供大家使用
研究後發現,無論是哪種類型的影片,
製作上大致可以歸類出四個步驟:
由於公司影片大多於攝影棚拍攝,且上傳的平台相同,
各個類型影片的差異,主要是在主題發想與剪輯。
<?php
namespace App\TemplateMethodPattern\Video;
abstract class BasicVideo
{
public function make()
{
return $this->generateIdeas() . '、' .
$this->shoot() . '、' .
$this->editing() . '、' .
$this->upload();
}
protected function shoot()
{
return '拍攝';
}
protected function upload()
{
return '上傳影片';
}
abstract protected function generateIdeas();
abstract protected function editing();
}
在make()方法中,我們定義了一個影片產生的流程。
而拍攝與上傳是每種類型影片的共同行為,
我們定義在shoot()方法及upload()方法中。
需求二:替各種類型的影片不同的部分作客製化
<?php
namespace App\TemplateMethodPattern\Video;
use App\TemplateMethodPattern\Video\BasicVideo;
class UnboxVideo extends BasicVideo
{
protected function generateIdeas()
{
return '選擇開箱項目';
}
protected function editing()
{
return '剪輯出個人開箱的風格';
}
}
<?php
namespace App\TemplateMethodPattern\Video;
use App\TemplateMethodPattern\Video\BasicVideo;
class TutorialVideo extends BasicVideo
{
protected function generateIdeas()
{
return '設計教學內容';
}
protected function editing()
{
return '剪輯出個人教學的風格';
}
}
<?php
namespace App\TemplateMethodPattern\Video;
use App\TemplateMethodPattern\Video\BasicVideo;
class StoryVideo extends BasicVideo
{
protected function generateIdeas()
{
return '選擇故事主題';
}
protected function editing()
{
return '剪輯出個人說故事的風格';
}
}
<?php
namespace App\TemplateMethodPattern\Video;
use App\TemplateMethodPattern\Video\UnboxVideo;
class Program
{
public function makeUnboxVideo()
{
$unboxVideo = new UnboxVideo();
return $unboxVideo->make();
}
public function makeTutorialVideo()
{
$tutorialVideo = new TutorialVideo();
return $tutorialVideo->make();
}
public function makeStoryVideo()
{
$storyVideo = new StoryVideo();
return $storyVideo->make();
}
}
[單一職責原則]
我們將製作影片的流程與製作影片的方式視作兩種不同的職責。
[開放封閉原則]
除了流程之外,不同影片的類型也歸類到不同的子類,
未來新增/修改影片類型製作方式時,也不會互相影響。
[依賴反轉原則]
客戶端的程式碼依賴抽象的父類基本影片。
不同類型的影片類別實作抽象的父類基本影片。
最後附上類別圖:
(註:若不熟悉 UML 類別圖,可參考UML類別圖說明。)
ʕ •ᴥ•ʔ:一個簡單易懂的模式,背後隱藏了很多設計模式的原則。